/** 
Copyright (c) 2010, Sheikh Abdul Wahid Ahmed
Details @ http://extremecodeworld.codeplex.com/license
**/

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using EXtremecode.PresentationLayer;

namespace EXtremecode.ASCX
{
    public partial class ASCXPager : System.Web.UI.UserControl,IPager 
    {
        public event PageLinkClickDelegate PageLinkClick;
        protected void Page_Load(object sender, EventArgs e)
        {

            LoadPager();
        }

        private void CreateAndPopulateDisplayLinks()
        {
            int totalPages = TotalPages;
            tblRowPagesLinks.Controls.Clear();
            if (totalPages == 0)
            {
                tblCellFistPage.Visible = false;
                tblCellLastPage.Visible = false;
                return;
            }

            //first link
            tblCellFistPage.Visible = (CurrentPageNumber > 1);

            //last link
            tblCellLastPage.Visible = (CurrentPageNumber < totalPages);


            //numeric links.
            int firstDisplayPageNumber, lastDisplayPageNumber;
            Pager.GetFirstAndLastDisplayPageNumbers(CurrentPageNumber, totalPages, NumberOfDisplayPages,
                out firstDisplayPageNumber, out lastDisplayPageNumber);

            for (int i = firstDisplayPageNumber; i <= lastDisplayPageNumber; i++)
            {
                TableCell cell = new TableCell();
                if (i != firstDisplayPageNumber)
                {
                    cell.Controls.Add(new LiteralControl("&nbsp;"));
                }

                string displayText = i.ToString("N0");
                if (i == CurrentPageNumber)
                {
                    //---create label
                    Label lbl = new Label();
                    lbl.Text = displayText;
                    cell.Controls.Add(lbl);
                }
                else
                {
                    //---create button
                    LinkButton btn = new LinkButton();
                    btn.Text = displayText;

                    //indication of more pages
                    if (i == firstDisplayPageNumber && i > 1)
                    {
                        btn.Text = "..." + btn.Text;
                    }
                    if (i == lastDisplayPageNumber && i < totalPages)
                    {
                        btn.Text = btn.Text + "...";
                    }
                    btn.ID = "btn" + i.ToString();
                    //name is mandatory otherwise we will observe unknown problem in calling of handler.

                    btn.CommandArgument = i.ToString();
                    btn.Command += new CommandEventHandler(PageLinkButton_Command);
                    cell.Controls.Add(btn);
                }

                tblRowPagesLinks.Controls.Add(cell);
            }
        }

        private void SetDisplayMessage()
        {
            if (CurrentPageNumber < 0 || TotalRecords <= 0)
            {
                return;
            }

            long pageFirstRecordNum = (PageSize * (CurrentPageNumber - 1)) + 1;
            long pageLastRecordNum = (TotalRecords < pageFirstRecordNum + PageSize - 1) ?
            TotalRecords : pageFirstRecordNum + PageSize - 1;
            string str = string.Format(ResourceProvider.GetGeneralResourceString("Caption_NumberOfRecords"),
                pageFirstRecordNum.ToString("N0"),
                pageLastRecordNum.ToString("N0"),
                TotalRecords.ToString("N0"));

            lblRecordsInfo.Text = str;

        }


        protected void PageLinkButton_Command(object sender, CommandEventArgs e)
        {
            CurrentPageNumber = Convert.ToInt32(e.CommandArgument);
            if (PageLinkClick != null)
            {
                PageLinkClick(new PageLinkClickEventArgs(CurrentPageNumber,PageSize));
            }
        }

     
        protected void cmbPageSize_SelectedIndexChanged(object sender, EventArgs e)
        {
            PageSize = Convert.ToInt32(cmbPageSize.SelectedValue);
            LoadPager();
            if (PageLinkClick != null)
            {
                PageLinkClick(new PageLinkClickEventArgs(CurrentPageNumber, PageSize));
            }
        }

        private void LoadPager()
        {
            CreateAndPopulateDisplayLinks();
            SetDisplayMessage();
        }

        #region IPager Members

        public int TotalPages
        {
            get
            {
                return (int)Math.Ceiling(((double)TotalRecords) / PageSize);
            }

        }

        public long TotalRecords
        {
            get
            {
                if (ViewState["TotalRecords"] == null)
                {
                    ViewState["TotalRecords"] = 0;
                }
                return Convert.ToInt64(ViewState["TotalRecords"]);
            }
            set
            {
                ViewState["TotalRecords"] = value;
                btnLastPage.CommandArgument = TotalPages.ToString();
                SetVisibility();
            }
        }

        public int PageSize
        {
            get
            {
                if (ViewState["PageSize"] == null)
                {
                    ViewState["PageSize"] = 10;
                }
                return Convert.ToInt32(ViewState["PageSize"]);
            }
            set
            {
                ViewState["PageSize"] = value;

                cmbPageSize.SelectedValue = value.ToString();
                btnLastPage.CommandArgument = TotalPages.ToString(); //last page num now has been changed.
                CurrentPageNumber = 1; //initialize;
            }
        }

        public int CurrentPageNumber
        {
            get
            {
                if (ViewState["CurrentPageNumber"] == null)
                {
                    ViewState["CurrentPageNumber"] = 1;
                }
                return Convert.ToInt32(ViewState["CurrentPageNumber"]);
            }
            set
            {
                ViewState["CurrentPageNumber"] = value;

                //following methods are using its getter.
                LoadPager();
                SetVisibility();
            }
        }

        public int NumberOfDisplayPages
        {
            get
            {
                if (ViewState["NumberOfDisplayPages"] == null)
                {
                    ViewState["NumberOfDisplayPages"] = 10;
                }
                return Convert.ToInt32(ViewState["NumberOfDisplayPages"]);
            }
            set
            {
                ViewState["NumberOfDisplayPages"] = value;
            }
        }

        public string PageSizesList
        {
            get
            {
                return ViewState["PageSizesList"] as string;
            }
            set
            {

                cmbPageSize.Items.Clear();
                foreach (string str in value.Split(','))
                {
                    int pageSize = 0;
                    if (int.TryParse(str, out pageSize))
                    {
                        if (cmbPageSize.Items.FindByValue(pageSize.ToString()) == null)
                        {
                            cmbPageSize.Items.Add(pageSize.ToString());
                        }
                    }
                }
                ViewState["PageSizesList"] = value;
            }
        }
        private void SetVisibility()
        {
            if (CurrentPageNumber <= 0 || TotalRecords <= 0)
            {
                this.Visible = false;
            }
            else
            {
                this.Visible = true;
            }
        }

        #endregion
    }
}